﻿#include "CVlcSdkOper.h"
#include<QThread>
#include <qmessagebox.h>
#include <windows.h>
#include <qdebug.h>
#include <QtConcurrent/QtConcurrentRun>
#include <QFuture>
#include <QFutureWatcher>
#include <QEventLoop>
#include <QTimer>
#include <qpointer.h>
#include <qdatetime.h>
#include <QDir>
#include <QCoreApplication>
static libvlc_instance_t* g_instance = nullptr;


bool CVlcSdkOper::stopVlcPlayerSafe(libvlc_media_player_t* player, int timeoutMs)
{
	if (!player) return false;
	libvlc_event_attach(libvlc_media_player_event_manager(player), libvlc_MediaPlayerStopped, &CVlcSdkOper::onVlcStopped, this);
	// 异步停止操作
	QFuture<void> future = QtConcurrent::run([player]() {
		try {
			libvlc_media_player_stop(player); // 可能阻塞
		}
		catch (const std::exception& e) {
			qWarning() << "[stopVlcPlayerSafe] 捕获异常:" << e.what();
		}
		catch (...) {
			qWarning() << "[stopVlcPlayerSafe] 捕获未知异常";
		}
		});

	// 监控 future
	QFutureWatcher<void> watcher;
	watcher.setFuture(future);

	// 创建事件循环，等待完成或超时
	QEventLoop loop;
	QObject::connect(&watcher, &QFutureWatcher<void>::finished, &loop, &QEventLoop::quit);

	QTimer timer;
	timer.setSingleShot(true);
	QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);

	timer.start(timeoutMs);
	loop.exec(); // 等待子线程完成或超时

	if (!future.isFinished()) 
	{
		return false;
	}
	else
	{
		return true;
	}
}



CVlcSdkOper::CVlcSdkOper()
{
	m_bRealPlay = false;
	if (!g_instance) 
	{
		const char* args[] = { "--intf=dummy", "--no-xlib", "--no-video-title-show" };
		g_instance = libvlc_new(sizeof(args) / sizeof(args[0]), args);
	}
	m_bStopped = false;
	m_pVlcInstance = g_instance;
	m_pVlcMediaPlayer = libvlc_media_player_new(m_pVlcInstance); // 创建一个媒体播放器MediaPlayer
}

CVlcSdkOper::~CVlcSdkOper()
{
	if (m_pMedia != nullptr)
	{
		libvlc_media_release(m_pMedia);
		m_pMedia = nullptr;
	}
	if (m_pVlcMediaPlayer != nullptr)
	{
		libvlc_media_player_release(m_pVlcMediaPlayer);
		m_pVlcMediaPlayer = nullptr;
	}
}

bool CVlcSdkOper::realPlay(const QString sRtspUrl, WId winId)
{
	if (m_bRealPlay)
	{
		return true;
	}
	if (m_pVlcMediaPlayer == nullptr)
	{
		return false;
	}
	libvlc_media_player_set_hwnd(m_pVlcMediaPlayer, reinterpret_cast<void*>(winId));
	m_pMedia = libvlc_media_new_location(m_pVlcInstance, sRtspUrl.toStdString().c_str());
	if (m_pMedia == nullptr)
	{
		return false;
	}
	libvlc_media_player_set_media(m_pVlcMediaPlayer, m_pMedia);
	if (libvlc_media_player_play(m_pVlcMediaPlayer) == 0)
	{
		m_bStopped = false;
		m_bRealPlay = true;
		return true;
	}
	else
	{
		m_bStopped = true;
		m_bRealPlay = false;
		return false;
	}
}

bool CVlcSdkOper::realPlay(const QString sRtspUrl, WId winId, QString & sReInfo)
{
	if (m_bRealPlay)
	{
		return true;
	}
	if (m_pVlcMediaPlayer == nullptr)
	{
		return false;
	}
	if (m_pMedia == nullptr)
	{
		m_pMedia = libvlc_media_new_location(m_pVlcInstance, sRtspUrl.toStdString().c_str());
		if (m_pMedia == nullptr)
		{
			sReInfo = "libvlc_media_new_location fail";
			return false;
		}
	}
	libvlc_media_player_set_media(m_pVlcMediaPlayer, m_pMedia);
	libvlc_media_player_set_hwnd(m_pVlcMediaPlayer, reinterpret_cast<void*>(winId));
	if (libvlc_media_player_play(m_pVlcMediaPlayer) == 0)
	{
		sReInfo = "replay suc";
		m_bRealPlay = true;
		return true;
	}
	else
	{
		sReInfo = "replay fail";
		m_bRealPlay = false;
		return false;
	}
}


bool CVlcSdkOper::stopRealPlay()
{
	if (m_pVlcMediaPlayer == nullptr)
	{
		return false;
	}
	libvlc_media_player_set_pause(m_pVlcMediaPlayer, 1);  //暂停视频
	QThread::msleep(100);
	if (!stopVlcPlayerSafe(m_pVlcMediaPlayer, 2000))
	{
		m_pVlcMediaPlayer = nullptr;
		m_pMedia = nullptr;
		return false;
	}
	else
	{
		if (waitTime(1000, m_bStopped))
		{
			m_bRealPlay = false;
			return true;
		}
		else
		{
			m_pVlcMediaPlayer = nullptr;
			m_pMedia = nullptr;
			return false;
		}
	}
}

bool CVlcSdkOper::stopRealPlayEx()
{
	if (!m_bRealPlay)
	{
		return true;
	}
	else
	{
		libvlc_media_player_stop(m_pVlcMediaPlayer);//关闭视频
		m_bRealPlay = false;
		return true;
	}	
}

void CVlcSdkOper::setSuspendText(const QString sShowText, const int nColorType)
{
	if (m_pVlcMediaPlayer != nullptr)
	{
		libvlc_video_set_marquee_int(m_pVlcMediaPlayer, libvlc_marquee_Enable, 1);
		libvlc_video_set_marquee_string(m_pVlcMediaPlayer, libvlc_marquee_Text, sShowText.toStdString().c_str());
		libvlc_video_set_marquee_int(m_pVlcMediaPlayer, libvlc_marquee_Position, 9);
		libvlc_video_set_marquee_int(m_pVlcMediaPlayer, libvlc_marquee_X, 20);
		libvlc_video_set_marquee_int(m_pVlcMediaPlayer, libvlc_marquee_Y, 20);
		if (nColorType == 0)//绿色
		{
			libvlc_video_set_marquee_int(m_pVlcMediaPlayer, libvlc_marquee_Color, 0x00ff00);
		}
		else if (nColorType == 1)//红色
		{
			libvlc_video_set_marquee_int(m_pVlcMediaPlayer, libvlc_marquee_Color, 0xff0000);
		}
	}
}

void CVlcSdkOper::onVlcStopped(const libvlc_event_t*, void* opaque)
{
	auto* selfRaw = static_cast<CVlcSdkOper*>(opaque);
	QPointer<CVlcSdkOper> self = selfRaw;
	if (!self)
	{
		return;
	}
	self->m_bStopped = true;
}

bool CVlcSdkOper::waitTime(int nMs, bool& bRun)
{
	bool bOk = true;
	int nCount = nMs / 5;
	int nIndex = 0;
	while (!bRun)
	{
		QEventLoop loop;
		QTimer::singleShot(5, &loop, SLOT(quit()));
		loop.exec();
		if (nIndex > nCount)
		{
			bOk = false;
			break;
		}
		nIndex++;
	}
	return bOk;
}